<template>
  <div :id="propId" :ref="propRef" class="chart">
    <!-- 载波检测信息 -->
    <div class="info">
      <span v-if="zaiBoForm.center">
        中心频点:{{ zaiBoForm.center }}MHz 带宽:{{ zaiBoForm.bandwidth }}KHz
        幅度:{{ zaiBoForm.snr }}db
      </span>
    </div>
    <!-- 控制显示最大、最小、平均 -->
    <div class="linesCtl">
      <div class="item" @click="isPlay = !isPlay">
        {{ isPlay ? "暂停" : "继续" }}
      </div>
      <div class="item" @click="cutPicture($refs[propRef])">快照</div>
      <div
        class="item"
        :class="{ active: item.isChoosed }"
        @click="changeDetectType(item.value)"
        v-for="item in typeOptions"
        :key="item.value"
      >
        {{ item.label }}
      </div>
    </div>
  </div>
</template>

<script>
import axios from "axios";
// 用于绘制瀑布图、罗盘图、折线图的完整版js
import chart from "@/utils/chart.js";
import { cutPicture } from "@/utils/cutPictures";
export default {
  name: "PinPuChart",
  props: ["propId", "propRef", "url", "chartType"],
  data() {
    return {
      isPlay: true,
      // 折线图图表对象
      chart: null,
      // 折线图系列(坐标轴)对象
      series: null,
      maxVal: null, // 传入一组数据的最大值
      minVal: null, // 传入一组数据的最小值
      xAxisMin: 0,
      xAxisMax: 100,
      initXAxisMin: null,
      initXAxisMax: null,
      xInterval: [], // x坐标起始区间
      // 曲线对象 => 对应一条折线
      line: null,
      line2: null,
      line3: null,

      formatStatus: false, // 是否开启格式化模式
      disabledChange: false, // 禁止修改状态

      timerFlag: null, // 抽点用的防抖函数的延时器id
      typeOptions: [
        {
          label: "平均",
          value: "2",
          isChoosed: false,
        },
        {
          label: "最大",
          value: "3",
          isChoosed: false,
        },
        {
          label: "最小",
          value: "4",
          isChoosed: false,
        },
      ],
      fitFlag: false,
      zaiBoForm: {
        bandwidth: "",
        center: "",
        snr: "",
      },
    };
  },
  computed: {
    detectType() {
      const temArr = [];
      this.typeOptions.forEach((item) => {
        if (item.isChoosed) temArr.push(item.value);
      });
      return temArr;
    },
  },
  watch: {
    isPlay(val) {
      this.$emit("changePlayFlag", val);
    },
  },
  mounted() {
    this.initLineChart();
  },
  inject: ["userMark"],
  beforeDestroy() {
    this.chart = null;
    clearTimeout(this.timerFlag);
    this.timerFlag = null;
  },
  methods: {
    cutPicture,
    // 初始化折线图
    initLineChart(fb) {
      const that = this;
      this.chart = chart().lineChart({
        container: that.propId, // id
        background: {
          r: 60 / 255,
          g: 60 / 255,
          b: 60 / 255,
        },
      });
      // 设置折线图坐标基本样式和配置
      that.series = that.chart.addSeries({
        title: {
          text: "频谱图",
          left: that.$refs[that.propRef].clientWidth / 2,
          top: 10,
        },
        // x轴单位
        axisXUnits: {
          text: "频率/MHz",
          left: that.$refs[that.propRef].clientWidth / 2,
          top: that.$refs[that.propRef].clientHeight,
        },
        // y轴单位
        axisYUnits: {
          text: "强度/dBm",
          left: 10,
          top: that.$refs[that.propRef].clientHeight / 2,
        },
        // x轴标点数量
        xAxisMarkNum: 10,
        // y轴标点数量
        yAxisMarkNum: 5,
        // y轴左边距
        yAxisPadding: 75,
        // y轴右边距
        yAxisAnotherPadding: 20,
        // x轴下边距
        xAxisPadding: 40,
        // x轴上边距
        xAxisAnotherPadding: 30,
        // x轴坐标格式化
        xAxisMarkFormatter: (value) => {
          return Number(value / 1000).toFixed(2);
        },
        // y轴坐标格式化
        yAxisMarkFormatter: (value) => {
          return Number(value).toFixed(2);
        },
        // 坐标轴颜色
        axisColor: {
          r: 192 / 255,
          g: 224 / 255,
          b: 224 / 255,
        },
        // x轴最小刻度
        // minXInterval: 200,
      });
      // 设置折线图X轴最大区间 => 不配置的话默认设置为 [0, 100]
      // this.series.setMaxXInterval([this.xAxisMin, this.xAxisMax]);
      // 设置折线图Y轴区间 => 不配置的话默认设置为 [0, 100]
      this.series.setMaxYInterval([-110, -40]);

      // 给折线图添加鼠标移动事件
      this.series.setOnMouseMoveListener((x, y, event) => {
        this.xValue = x.toFixed(2);
        this.yValue = this.line.getYData(this.xValue);

        if (this.yValue !== null) {
          // console.log("折线图鼠标当前位置:", this.xValue, this.yValue);
          let value1;
          if (this.formatStatus) {
            value1 =
              ((this.xValue * (this.xAxisMax - this.xAxisMin)) / this.temMax +
                this.xAxisMin) /
              1000;
          } else {
            value1 = this.xValue / 1000;
          }
          this.series.addTooltip({
            value1,
            value2: this.yValue,
            left: that.$refs[that.propRef].clientWidth,
            top: 10,
          });
        }
      });
      // 给折线图添加点击事件
      this.series.setOnClickListener((x, y, event) => {
        // this.xClickValue = x.toFixed(2);
        // this.yClickValue = y.toFixed(2);
        const index = this.line.getIndex(x.toFixed(2));
        this.getZaiboInfoAPI(index)
          .then((res) => {
            // console.log('载波检测信息', res.data)
            if (res.data) {
              this.zaiBoForm.bandwidth = res.data.data.bandwidth;
              this.zaiBoForm.center = res.data.data.center;
              this.zaiBoForm.snr = res.data.data.snr;
            } else {
              this.zaiBoForm = {
                bandwidth: "",
                center: "",
                snr: "",
              };
            }
          })
          .catch((err) => {
            console.log(err);
          });
      });
      // 给图表添加被测量事件(画矩形事件) => 传入的回调即是绑定的事件
      this.series.setOnMeasureListener((startX, startY, endX, endY) => {
        // console.log('OnMeasureListener')
        this.startX = startX.toFixed(2);
        this.startY = startY.toFixed(2);
        this.endX = endX.toFixed(2);
        this.endY = endY.toFixed(2);
      });

      // 设置折线图X轴区间变化时的回调函数 => 变化时瀑布图x轴区间跟着变化同时刷新图表
      this.series.setOnXIntervalChange(async (newInterval) => {
        // 不调用接口修改频谱图范围了
        // 使用防抖函数，使其在缩放结束0.3s后再去调接口改数据
        // this.timerFlag && clearTimeout(this.timerFlag);
        // this.timerFlag = setTimeout(async () => {
        //   try {
        //     // 设置瀑布图x轴当前区间
        //     // this.series2.changeXInterval(newInterval)
        //     // console.log('newInterval', newInterval)
        //     const temInerval = newInterval;
        //     if (
        //       temInerval[0] === this.initXAxisMin &&
        //       temInerval[1] === this.initXAxisMax
        //     ) {
        //       temInerval[0] = 950000;
        //       temInerval[1] = 2150000;
        //       this.formatStatus = false;
        //       this.disabledChange = true;
        //       // console.log('恢复X坐标轴')
        //       this.series.setXAxisMarkFormatter((value) => {
        //         return Number(value / 1000).toFixed(2);
        //       });
        //       /* this.series2.setXAxisMarkFormatter((value) => {
        //         return Number(value / 1000).toFixed(2)
        //       }) */
        //       setTimeout(() => {
        //         this.disabledChange = false;
        //       }, 300);
        //     } else {
        //       if (this.formatStatus) {
        //         // console.log('newInterval', newInterval)
        //         temInerval[0] =
        //           (newInterval[0] * (this.xAxisMax - this.xAxisMin)) /
        //             this.temMax +
        //           this.xAxisMin;
        //         temInerval[1] =
        //           (newInterval[1] * (this.xAxisMax - this.xAxisMin)) /
        //             this.temMax +
        //           this.xAxisMin;
        //         // console.log('temInerval', temInerval)
        //         if (temInerval[1] - temInerval[0] >= 1000) {
        //           setTimeout(() => {
        //             this.formatStatus = false;
        //             // console.log('恢复X坐标轴')
        //             this.series.setXAxisMarkFormatter((value) => {
        //               return Number(value / 1000).toFixed(2);
        //             });
        //           }, 500);
        //         }
        //       }
        //     }
        //     if (this.chartType === 0) {
        //       // 扫频
        //       const startFre = temInerval[0].toFixed(0) / 1000;
        //       const stopFre = temInerval[1].toFixed(0) / 1000;
        //       this.$emit("changeCenterFre", startFre, stopFre);
        //     } else if (this.chartType === 1) {
        //       // 实时
        //       await this.setRangeAPI({
        //         from: temInerval[0],
        //         end: temInerval[1],
        //         userName: "1_123456789",
        //       });
        //     } else {
        //       // 回放
        //     }
        //   } catch (error) {
        //     console.log(error);
        //   }
        // }, 300);
      });

      // 设置折线图绘图曲线颜色 => 用line变量来接收addLine函数的返回结果，后续调用line上的方法来添加数据
      // 平均曲线
      this.line = this.series.addLine({
        color: {
          r: 0.87,
          g: 0.87,
          b: 0,
        },
      });

      // 最大曲线
      this.line2 = this.series.addLine({
        color: {
          r: 1,
          g: 0,
          b: 0,
        },
      });

      // 最小曲线
      this.line3 = this.series.addLine({
        color: {
          r: 0,
          g: 1,
          b: 0,
        },
      });

      this.chart.refresh();
      // 如果有回调函数就调用
      fb && fb();
    },

    // 绘图方法 => 重写版，可同时绘制1、2、3条曲线
    drawChart(chartData, startFreq, endFreq, initStart, initEnd) {
      if (!chartData.fFTRealtime || !chartData.fFTRealtime.length) {
        return;
      }

      if (this.formatStatus) {
        const temStart =
          0 -
          (
            ((startFreq - initStart) *
              (chartData.fFTRealtime.length / (endFreq - startFreq))) /
            1000
          ).toFixed(0);
        const temEnd =
          chartData.fFTRealtime.length +
          (
            ((initEnd - startFreq) *
              (chartData.fFTRealtime.length / (endFreq - startFreq))) /
            1000
          ).toFixed(0) *
            1;
        // console.log('初始最大最小值', temStart, temEnd, chartData.fFTRealtime.length)
        this.initXAxisMin = temStart;
        this.initXAxisMax = temEnd;
        // 重新设置折线图/瀑布图x轴最大区间
        // 重新设置折线图/瀑布图x轴最大区间
        this.series.setMaxXInterval([temStart, temEnd]);
        this.series.changeXInterval([0, this.temMax]);
      } else if (
        !this.formatStatus &&
        (this.initXAxisMin !== initStart || this.initXAxisMax !== initEnd)
      ) {
        this.initXAxisMin = initStart;
        this.initXAxisMax = initEnd;
        // 重新设置折线图/瀑布图x轴最大区间
        this.changeMaxInterval();
        // this.xAxisMin = startFreq;
        // this.xAxisMax = endFreq;
        // 重新设置折线图/瀑布图x轴当前区间
        // this.changeInterval();
      }

      /* if (
        this.formatStatus &&
        this.temMax !== chartData.fFTRealtime.length - 1
      ) { */
      // 这里去掉了 与 this.temMax !== chartData.fFTRealtime.length - 1判断，忘了当初怎么想的了
      if (this.formatStatus) {
        this.temMax = chartData.fFTRealtime.length - 1;
        this.xAxisMin = startFreq;
        this.xAxisMax = endFreq;
        this.series.changeXInterval([0, this.temMax]);
        // console.log('格式化X坐标轴')
        this.series.setXAxisMarkFormatter((value) => {
          return (
            (startFreq +
              (endFreq - startFreq) * (value / chartData.fFTRealtime.length)) /
            1000
          ).toFixed(2);
        });
      } else if (
        !this.formatStatus &&
        (this.xAxisMax !== endFreq || this.xAxisMin !== startFreq)
      ) {
        this.xAxisMin = startFreq;
        this.xAxisMax = endFreq;
        // 重新设置折线图/瀑布图x轴当前区间
        this.changeInterval();
      }

      // 图表实际的x、y数据
      const temArr1 = []; // 平均曲线
      const temArr2 = []; // 最大曲线
      const temArr3 = []; // 最小曲线
      const increase = (endFreq - startFreq) / chartData.fFTRealtime.length;

      // 首次收到数据、参数修改后 => 求曲线Y轴的最大最小值，实现Y轴自适应
      if (this.fitFlag) {
        let maxYVal, minYVal;
        // console.log('chartData', chartData)
        if (chartData.fFTMax && chartData.fFTMax.length) {
          maxYVal = Math.max.apply(null, chartData.fFTMax);
        } else if (chartData.fFTAvg && chartData.fFTAvg.length) {
          maxYVal = Math.max.apply(null, chartData.fFTAvg);
        } else if (chartData.fFTMin && chartData.fFTMin.length) {
          maxYVal = Math.max.apply(null, chartData.fFTMin);
        }

        if (chartData.fFTMin && chartData.fFTMin.length) {
          minYVal = Math.min.apply(null, chartData.fFTMin);
        } else if (chartData.fFTAvg && chartData.fFTAvg.length) {
          minYVal = Math.min.apply(null, chartData.fFTAvg);
        } else if (chartData.fFTMax && chartData.fFTMax.length) {
          minYVal = Math.min.apply(null, chartData.fFTMax);
        }

        // 重新设置折线图Y轴区间
        maxYVal &&
          minYVal &&
          this.$emit(
            "changeYRange",
            maxYVal + (maxYVal - minYVal) * 0.05,
            minYVal - (maxYVal - minYVal) * 0.05
          );

        this.fitFlag = false;
      }

      if (!this.formatStatus) {
        chartData.fFTRealtime.forEach((item, index) => {
          // 填入频谱图数据
          if (chartData.fFTAvg) {
            // 平均曲线
            temArr1.push(startFreq + index * increase);
            temArr1.push(chartData.fFTAvg[index]);
          }
          if (chartData.fFTMax) {
            // 最大曲线
            temArr2.push(startFreq + index * increase);
            temArr2.push(chartData.fFTMax[index]);
          }
          if (chartData.fFTMin) {
            // 最小曲线
            temArr3.push(startFreq + index * increase);
            temArr3.push(chartData.fFTMin[index]);
          }
        });
      } else {
        chartData.fFTRealtime.forEach((item, index) => {
          // 填入频谱图数据
          if (chartData.fFTAvg) {
            // 平均曲线
            temArr1.push(index);
            temArr1.push(chartData.fFTAvg[index]);
          }
          if (chartData.fFTMax) {
            // 最大曲线
            temArr2.push(index);
            temArr2.push(chartData.fFTMax[index]);
          }
          if (chartData.fFTMin) {
            // 最小曲线
            temArr3.push(index);
            temArr3.push(chartData.fFTMin[index]);
          }
        });
      }
      // console.log(this.xAxisMin, this.xAxisMax, this.minVal, this.maxVal)
      // console.log('格式化模式', this.formatStatus)
      chartData.fFTAvg && this.line.setData(temArr1);
      chartData.fFTMax && this.line2.setData(temArr2);
      chartData.fFTMin && this.line3.setData(temArr3);
      this.chart.refresh();
    },

    // 设置折线/瀑布图X轴当前区间
    changeInterval() {
      this.series.setMaxXInterval([this.xAxisMin, this.xAxisMax]);
      // this.series.changeXInterval([this.xAxisMin, this.xAxisMax]);
    },
    // 设置折线/瀑布图X轴最大区间
    changeMaxInterval() {
      this.series.setMaxXInterval([this.xAxisMin, this.xAxisMax]);

      /* if (this.initXAxisMin !== null) {
        this.series.setMaxXInterval([this.initXAxisMin, this.initXAxisMax]);
      } else {
        this.series.setMaxXInterval([this.xAxisMin, this.xAxisMax]);
      } */
    },
    setRangeAPI(data) {
      let url;
      if (this.propRef === "canvas1" || this.propRef === "canvas2") {
        url = this.url[0];
      } else {
        url = this.url[1];
      }
      return axios({
        url: "http://" + url + "/interface/range/set",
        method: "post",
        data,
      });
    },
    // 修改展示曲线的类型
    async changeDetectType(val) {
      this.typeOptions.some((item) => {
        if (item.value === val) {
          item.isChoosed = !item.isChoosed;
          return true;
        }
      });

      if (!this.detectType.includes("2")) {
        this.$emit("showLine", "line", false);
      } else {
        this.$emit("showLine", "line", true);
      }
      if (!this.detectType.includes("3")) {
        this.$emit("showLine", "line2", false);
      } else {
        this.$emit("showLine", "line2", true);
      }
      if (!this.detectType.includes("4")) {
        this.$emit("showLine", "line3", false);
      } else {
        this.$emit("showLine", "line3", true);
      }
      // this.sweepConfig()
      try {
        await this.changeDetectTypeAPI({
          detectType: this.detectType.join(","),
        });
        this.$message.success("配置成功！");
        // this.changeFitFlag();
      } catch (error) {
        console.log(error);
        this.$message.error("操作失败！");
      }
    },
    changeDetectTypeAPI(data) {
      let url;
      if (this.propRef === "canvas1" || this.propRef === "canvas2") {
        url = this.url[0];
      } else {
        url = this.url[1];
      }
      return axios({
        url: "http://" + url + "/interface/fft/detectType",
        method: "post",
        data,
      });
    },
    changeFitFlag() {
      setTimeout(() => {
        this.fitFlag = true;
      }, 500);
    },
    getZaiboInfoAPI(params) {
      let url;
      if (this.propRef === "canvas1" || this.propRef === "canvas2") {
        url = this.url[0];
      } else {
        url = this.url[1];
      }
      return axios({
        url: "http://" + url + "/interface/zaibo/" + params,
        method: "get",
      });
    },
  },
};
</script>

<style lang="scss" scoped>
.chart {
  position: relative;
  .linesCtl {
    position: absolute;
    right: 25px;
    bottom: 50px;
    width: 270px;
    height: 24px;
    line-height: 24px;
    font-size: 16px;

    display: flex;
    justify-content: space-around;
    align-items: center;
    flex-wrap: nowrap;

    .item {
      width: 50px;
      background-color: rgba(60, 60, 60, 0.8);
      color: #90a8a8;
      cursor: pointer;
      z-index: 99;
      text-align: center;

      &.active {
        background-color: rgba(77, 96, 129, 0.8);
        color: #fff;
      }
    }
  }

  .info {
    position: absolute;
    top: 0px;
    left: 5px;
    min-width: 100px;
    height: 20px;
    line-height: 20px;
    background: #3c3c3c;
    color: #9fb7b7;
    font-size: 12px;
  }
}
</style>
